home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 21 / AACD 21.iso / AACD / Utilities / Ghostscript / src / gxp1fill.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-01-01  |  12.5 KB  |  396 lines

  1. /* Copyright (C) 1998, 1999 Aladdin Enterprises.  All rights reserved.
  2.   
  3.   This file is part of AFPL Ghostscript.
  4.   
  5.   AFPL Ghostscript is distributed with NO WARRANTY OF ANY KIND.  No author or
  6.   distributor accepts any responsibility for the consequences of using it, or
  7.   for whether it serves any particular purpose or works at all, unless he or
  8.   she says so in writing.  Refer to the Aladdin Free Public License (the
  9.   "License") for full details.
  10.   
  11.   Every copy of AFPL Ghostscript must include a copy of the License, normally
  12.   in a plain ASCII text file named PUBLIC.  The License grants you the right
  13.   to copy, modify and redistribute AFPL Ghostscript, but only under certain
  14.   conditions described in the License.  Among other things, the License
  15.   requires that the copyright notice and this notice be preserved on all
  16.   copies.
  17. */
  18.  
  19. /*$Id: gxp1fill.c,v 1.2 2000/09/19 19:00:39 lpd Exp $ */
  20. /* PatternType 1 filling algorithms */
  21. #include "math_.h"
  22. #include "gx.h"
  23. #include "gserrors.h"
  24. #include "gsrop.h"
  25. #include "gsmatrix.h"
  26. #include "gxcspace.h"        /* for gscolor2.h */
  27. #include "gxcolor2.h"
  28. #include "gxdcolor.h"
  29. #include "gxdevcli.h"
  30. #include "gxdevmem.h"
  31. #include "gxclip2.h"
  32. #include "gxpcolor.h"
  33. #include "gxp1impl.h"
  34.  
  35. /* Define the state for tile filling. */
  36. typedef struct tile_fill_state_s {
  37.  
  38.     /* Original arguments */
  39.  
  40.     const gx_device_color *pdevc;    /* pattern color */
  41.     int x0, y0, w0, h0;
  42.     gs_logical_operation_t lop;
  43.     const gx_rop_source_t *source;
  44.  
  45.     /* Variables set at initialization */
  46.  
  47.     gx_device_tile_clip cdev;
  48.     gx_device *pcdev;        /* original device or &cdev */
  49.     const gx_strip_bitmap *tmask;
  50.     gs_int_point phase;
  51.  
  52.     /* Following are only for uncolored patterns */
  53.  
  54.     dev_color_proc_fill_rectangle((*fill_rectangle));
  55.  
  56.     /* Following are only for colored patterns */
  57.  
  58.     const gx_rop_source_t *rop_source;
  59.     gx_device *orig_dev;
  60.     int xoff, yoff;        /* set dynamically */
  61.  
  62. } tile_fill_state_t;
  63.  
  64. /* Initialize the filling state. */
  65. private int
  66. tile_fill_init(tile_fill_state_t * ptfs, const gx_device_color * pdevc,
  67.            gx_device * dev, bool set_mask_phase)
  68. {
  69.     gx_color_tile *m_tile = pdevc->mask.m_tile;
  70.     int px, py;
  71.  
  72.     ptfs->pdevc = pdevc;
  73.     if (m_tile == 0) {        /* no clipping */
  74.     ptfs->pcdev = dev;
  75.     ptfs->phase = pdevc->phase;
  76.     return 0;
  77.     }
  78.     ptfs->pcdev = (gx_device *) & ptfs->cdev;
  79.     ptfs->tmask = &m_tile->tmask;
  80.     ptfs->phase.x = pdevc->mask.m_phase.x;
  81.     ptfs->phase.y = pdevc->mask.m_phase.y;
  82.     /*
  83.      * For non-simple tiles, the phase will be reset on each pass of the
  84.      * tile_by_steps loop, but for simple tiles, we must set it now.
  85.      */
  86.     if (set_mask_phase && m_tile->is_simple) {
  87.     px = imod(-(int)(m_tile->step_matrix.tx - ptfs->phase.x + 0.5),
  88.           m_tile->tmask.rep_width);
  89.     py = imod(-(int)(m_tile->step_matrix.ty - ptfs->phase.y + 0.5),
  90.           m_tile->tmask.rep_height);
  91.     } else
  92.     px = py = 0;
  93.     return tile_clip_initialize(&ptfs->cdev, ptfs->tmask, dev, px, py, NULL);
  94. }
  95.  
  96. /*
  97.  * Fill with non-standard X and Y stepping.
  98.  * ptile is pdevc->colors.pattern.{m,p}_tile.
  99.  * tbits_or_tmask is whichever of tbits and tmask is supplying
  100.  * the tile size.
  101.  * This implementation could be sped up considerably!
  102.  */
  103. private int
  104. tile_by_steps(tile_fill_state_t * ptfs, int x0, int y0, int w0, int h0,
  105.           const gx_color_tile * ptile,
  106.           const gx_strip_bitmap * tbits_or_tmask,
  107.           int (*fill_proc) (P5(const tile_fill_state_t * ptfs,
  108.                    int x, int y, int w, int h)))
  109. {
  110.     int x1 = x0 + w0, y1 = y0 + h0;
  111.     int i0, i1, j0, j1, i, j;
  112.     gs_matrix step_matrix;    /* translated by phase */
  113.     int code;
  114.  
  115.     ptfs->x0 = x0, ptfs->w0 = w0;
  116.     ptfs->y0 = y0, ptfs->h0 = h0;
  117.     step_matrix = ptile->step_matrix;
  118.     step_matrix.tx -= ptfs->phase.x;
  119.     step_matrix.ty -= ptfs->phase.y;
  120.     {
  121.     gs_rect bbox;        /* bounding box in device space */
  122.     gs_rect ibbox;        /* bounding box in stepping space */
  123.     double bbw = ptile->bbox.q.x - ptile->bbox.p.x;
  124.     double bbh = ptile->bbox.q.y - ptile->bbox.p.y;
  125.     double u0, v0, u1, v1;
  126.  
  127.     bbox.p.x = x0, bbox.p.y = y0;
  128.     bbox.q.x = x1, bbox.q.y = y1;
  129.     gs_bbox_transform_inverse(&bbox, &step_matrix, &ibbox);
  130.     if_debug10('T',
  131.       "[T]x,y=(%d,%d) w,h=(%d,%d) => (%g,%g),(%g,%g), offset=(%g,%g)\n",
  132.            x0, y0, w0, h0,
  133.            ibbox.p.x, ibbox.p.y, ibbox.q.x, ibbox.q.y,
  134.            step_matrix.tx, step_matrix.ty);
  135.     /*
  136.      * If the pattern is partly transparent and XStep/YStep is smaller
  137.      * than the device space BBox, we need to ensure that we cover
  138.      * each pixel of the rectangle being filled with *every* pattern
  139.      * that overlaps it, not just *some* pattern copy.
  140.      */
  141.     u0 = ibbox.p.x - max(ptile->bbox.p.x, 0) - 0.000001;
  142.     v0 = ibbox.p.y - max(ptile->bbox.p.y, 0) - 0.000001;
  143.     u1 = ibbox.q.x - min(ptile->bbox.q.x, 0) + 0.000001;
  144.     v1 = ibbox.q.y - min(ptile->bbox.q.y, 0) + 0.000001;
  145.     if (!ptile->is_simple)
  146.         u0 -= bbw, v0 -= bbh, u1 += bbw, v1 += bbh;
  147.     i0 = (int)floor(u0);
  148.     j0 = (int)floor(v0);
  149.     i1 = (int)ceil(u1);
  150.     j1 = (int)ceil(v1);
  151.     }
  152.     if_debug4('T', "[T]i=(%d,%d) j=(%d,%d)\n", i0, i1, j0, j1);
  153.     for (i = i0; i < i1; i++)
  154.     for (j = j0; j < j1; j++) {
  155.         int x = (int)(step_matrix.xx * i +
  156.               step_matrix.yx * j + step_matrix.tx);
  157.         int y = (int)(step_matrix.xy * i +
  158.               step_matrix.yy * j + step_matrix.ty);
  159.         int w = tbits_or_tmask->size.x;
  160.         int h = tbits_or_tmask->size.y;
  161.         int xoff, yoff;
  162.  
  163.         if_debug4('T', "[T]i=%d j=%d x,y=(%d,%d)", i, j, x, y);
  164.         if (x < x0)
  165.         xoff = x0 - x, x = x0, w -= xoff;
  166.         else
  167.         xoff = 0;
  168.         if (y < y0)
  169.         yoff = y0 - y, y = y0, h -= yoff;
  170.         else
  171.         yoff = 0;
  172.         if (x + w > x1)
  173.         w = x1 - x;
  174.         if (y + h > y1)
  175.         h = y1 - y;
  176.         if_debug6('T', "=>(%d,%d) w,h=(%d,%d) x/yoff=(%d,%d)\n",
  177.               x, y, w, h, xoff, yoff);
  178.         if (w > 0 && h > 0) {
  179.         if (ptfs->pcdev == (gx_device *) & ptfs->cdev)
  180.             tile_clip_set_phase(&ptfs->cdev,
  181.                 imod(xoff - x, ptfs->tmask->rep_width),
  182.                 imod(yoff - y, ptfs->tmask->rep_height));
  183.         /* Set the offsets for colored pattern fills */
  184.         ptfs->xoff = xoff;
  185.         ptfs->yoff = yoff;
  186.         code = (*fill_proc) (ptfs, x, y, w, h);
  187.         if (code < 0)
  188.             return code;
  189.         }
  190.     }
  191.     return 0;
  192. }
  193.  
  194. /* Fill a rectangle with a colored Pattern. */
  195. /* Note that we treat this as "texture" for RasterOp. */
  196. private int
  197. tile_colored_fill(const tile_fill_state_t * ptfs,
  198.           int x, int y, int w, int h)
  199. {
  200.     gx_color_tile *ptile = ptfs->pdevc->colors.pattern.p_tile;
  201.     gs_logical_operation_t lop = ptfs->lop;
  202.     const gx_rop_source_t *source = ptfs->source;
  203.     const gx_rop_source_t *rop_source = ptfs->rop_source;
  204.     gx_device *dev = ptfs->orig_dev;
  205.     int xoff = ptfs->xoff, yoff = ptfs->yoff;
  206.     gx_strip_bitmap *bits = &ptile->tbits;
  207.     const byte *data = bits->data;
  208.     bool full_transfer = (w == ptfs->w0 && h == ptfs->h0);
  209.     gx_bitmap_id source_id =
  210.     (full_transfer ? rop_source->id : gx_no_bitmap_id);
  211.     int code;
  212.  
  213.     if (source == NULL && lop_no_S_is_T(lop))
  214.     code = (*dev_proc(ptfs->pcdev, copy_color))
  215.         (ptfs->pcdev, data + bits->raster * yoff, xoff,
  216.          bits->raster,
  217.          (full_transfer ? bits->id : gx_no_bitmap_id),
  218.          x, y, w, h);
  219.     else {
  220.     gx_strip_bitmap data_tile;
  221.  
  222.     data_tile.data = (byte *) data;        /* actually const */
  223.     data_tile.raster = bits->raster;
  224.     data_tile.size.x = data_tile.rep_width = ptile->tbits.size.x;
  225.     data_tile.size.y = data_tile.rep_height = ptile->tbits.size.y;
  226.     data_tile.id = bits->id;
  227.     data_tile.shift = data_tile.rep_shift = 0;
  228.     code = (*dev_proc(dev, strip_copy_rop))
  229.         (dev,
  230.          rop_source->sdata + (y - ptfs->y0) * rop_source->sraster,
  231.          rop_source->sourcex + (x - ptfs->x0),
  232.          rop_source->sraster, source_id,
  233.          (rop_source->use_scolors ? rop_source->scolors : NULL),
  234.          &data_tile, NULL,
  235.          x, y, w, h,
  236.          imod(xoff - x, data_tile.rep_width),
  237.          imod(yoff - y, data_tile.rep_height),
  238.          lop);
  239.     }
  240.     return code;
  241. }
  242. int
  243. gx_dc_pattern_fill_rectangle(const gx_device_color * pdevc, int x, int y,
  244.                  int w, int h, gx_device * dev,
  245.                  gs_logical_operation_t lop,
  246.                  const gx_rop_source_t * source)
  247. {
  248.     gx_color_tile *ptile = pdevc->colors.pattern.p_tile;
  249.     const gx_rop_source_t *rop_source = source;
  250.     gx_rop_source_t no_source;
  251.     gx_strip_bitmap *bits;
  252.     tile_fill_state_t state;
  253.     int code;
  254.  
  255.     if (ptile == 0)        /* null pattern */
  256.     return 0;
  257.     if (rop_source == NULL)
  258.     set_rop_no_source(rop_source, no_source, dev);
  259.     bits = &ptile->tbits;
  260.     code = tile_fill_init(&state, pdevc, dev, false);
  261.     if (code < 0)
  262.     return code;
  263.     if (ptile->is_simple) {
  264.     int px =
  265.         imod(-(int)(ptile->step_matrix.tx - state.phase.x + 0.5),
  266.          bits->rep_width);
  267.     int py =
  268.         imod(-(int)(ptile->step_matrix.ty - state.phase.y + 0.5),
  269.          bits->rep_height);
  270.  
  271.     if (state.pcdev != dev)
  272.         tile_clip_set_phase(&state.cdev, px, py);
  273.     if (source == NULL && lop_no_S_is_T(lop))
  274.         code = (*dev_proc(state.pcdev, strip_tile_rectangle))
  275.         (state.pcdev, bits, x, y, w, h,
  276.          gx_no_color_index, gx_no_color_index, px, py);
  277.     else
  278.         code = (*dev_proc(state.pcdev, strip_copy_rop))
  279.         (state.pcdev,
  280.          rop_source->sdata, rop_source->sourcex,
  281.          rop_source->sraster, rop_source->id,
  282.          (rop_source->use_scolors ? rop_source->scolors : NULL),
  283.          bits, NULL, x, y, w, h, px, py, lop);
  284.     } else {
  285.     state.lop = lop;
  286.     state.source = source;
  287.     state.rop_source = rop_source;
  288.     state.orig_dev = dev;
  289.     code = tile_by_steps(&state, x, y, w, h, ptile,
  290.                  &ptile->tbits, tile_colored_fill);
  291.     }
  292.     return code;
  293. }
  294.  
  295. /* Fill a rectangle with an uncolored Pattern. */
  296. /* Note that we treat this as "texture" for RasterOp. */
  297. private int
  298. tile_masked_fill(const tile_fill_state_t * ptfs,
  299.          int x, int y, int w, int h)
  300. {
  301.     if (ptfs->source == NULL)
  302.     return (*ptfs->fill_rectangle)
  303.         (ptfs->pdevc, x, y, w, h, ptfs->pcdev, ptfs->lop, NULL);
  304.     else {
  305.     const gx_rop_source_t *source = ptfs->source;
  306.     gx_rop_source_t step_source;
  307.  
  308.     step_source.sdata = source->sdata + (y - ptfs->y0) * source->sraster;
  309.     step_source.sourcex = source->sourcex + (x - ptfs->x0);
  310.     step_source.sraster = source->sraster;
  311.     step_source.id = (w == ptfs->w0 && h == ptfs->h0 ?
  312.               source->id : gx_no_bitmap_id);
  313.     step_source.scolors[0] = source->scolors[0];
  314.     step_source.scolors[1] = source->scolors[1];
  315.     step_source.use_scolors = source->use_scolors;
  316.     return (*ptfs->fill_rectangle)
  317.         (ptfs->pdevc, x, y, w, h, ptfs->pcdev, ptfs->lop, &step_source);
  318.     }
  319. }
  320. int
  321. gx_dc_pure_masked_fill_rect(const gx_device_color * pdevc,
  322.                 int x, int y, int w, int h, gx_device * dev,
  323.                 gs_logical_operation_t lop,
  324.                 const gx_rop_source_t * source)
  325. {
  326.     gx_color_tile *ptile = pdevc->mask.m_tile;
  327.     tile_fill_state_t state;
  328.     int code;
  329.  
  330.     /*
  331.      * This routine should never be called if there is no masking,
  332.      * but we leave the checks below just in case.
  333.      */
  334.     code = tile_fill_init(&state, pdevc, dev, true);
  335.     if (code < 0)
  336.     return code;
  337.     if (state.pcdev == dev || ptile->is_simple)
  338.     return (*gx_dc_type_data_pure.fill_rectangle)
  339.         (pdevc, x, y, w, h, state.pcdev, lop, source);
  340.     else {
  341.     state.lop = lop;
  342.     state.source = source;
  343.     state.fill_rectangle = gx_dc_type_data_pure.fill_rectangle;
  344.     return tile_by_steps(&state, x, y, w, h, ptile, &ptile->tmask,
  345.                  tile_masked_fill);
  346.     }
  347. }
  348. int
  349. gx_dc_binary_masked_fill_rect(const gx_device_color * pdevc,
  350.                   int x, int y, int w, int h, gx_device * dev,
  351.                   gs_logical_operation_t lop,
  352.                   const gx_rop_source_t * source)
  353. {
  354.     gx_color_tile *ptile = pdevc->mask.m_tile;
  355.     tile_fill_state_t state;
  356.     int code;
  357.  
  358.     code = tile_fill_init(&state, pdevc, dev, true);
  359.     if (code < 0)
  360.     return code;
  361.     if (state.pcdev == dev || ptile->is_simple)
  362.     return (*gx_dc_type_data_ht_binary.fill_rectangle)
  363.         (pdevc, x, y, w, h, state.pcdev, lop, source);
  364.     else {
  365.     state.lop = lop;
  366.     state.source = source;
  367.     state.fill_rectangle = gx_dc_type_data_ht_binary.fill_rectangle;
  368.     return tile_by_steps(&state, x, y, w, h, ptile, &ptile->tmask,
  369.                  tile_masked_fill);
  370.     }
  371. }
  372. int
  373. gx_dc_colored_masked_fill_rect(const gx_device_color * pdevc,
  374.                    int x, int y, int w, int h, gx_device * dev,
  375.                    gs_logical_operation_t lop,
  376.                    const gx_rop_source_t * source)
  377. {
  378.     gx_color_tile *ptile = pdevc->mask.m_tile;
  379.     tile_fill_state_t state;
  380.     int code;
  381.  
  382.     code = tile_fill_init(&state, pdevc, dev, true);
  383.     if (code < 0)
  384.     return code;
  385.     if (state.pcdev == dev || ptile->is_simple)
  386.     return (*gx_dc_type_data_ht_colored.fill_rectangle)
  387.         (pdevc, x, y, w, h, state.pcdev, lop, source);
  388.     else {
  389.     state.lop = lop;
  390.     state.source = source;
  391.     state.fill_rectangle = gx_dc_type_data_ht_colored.fill_rectangle;
  392.     return tile_by_steps(&state, x, y, w, h, ptile, &ptile->tmask,
  393.                  tile_masked_fill);
  394.     }
  395. }
  396.